﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace LogWare.AppCode {
	public class ReportWriter : StreamWriter {
		public static class AsciiFonts {
			public const char UpperLeftCorner = '┌';
			public const char UpperRightCorner = '┐';
			public const char VerticalBar = '│';
			public const char HorizontalBar = '─';
			public const char Cross = '┼';
			public const char LowerLeftCorner = '└';
			public const char LowerRightCorner = '┘';
			public const char ConnectionRight = '├';
			public const char ConnectionUp = '┴';
			public const char ConnectionLeft = '┤';
			public const char ConnectionDown = '┬';
			public const char DoubleUpperLeftCorner = '╔';
			public const char DoubleUpperRightCorner = '╗';
			public const char DoubleLowerLeftCorner = '╚';
			public const char DoubleLowerRightCorner = '╝';
			public const char DoubleHorizontalBar = '═';
			public const char DoubleVerticalBar = '║';
			public const char DoubleConnectionDown = '╤';
			public const char DoubleConnectionLeft = '╢';
			public const char DoubleConnectionRight = '╟';
			public const char DoubleConnectionUp = '╧';
			public const char Space = ' ';
		}
		
		public int CurrentLine { get; private set; }
		public int CurrentColumn { get; private set; }

		public int MaxLineCharacters { get; set; }
		
		public ReportWriter(Stream stream) : base(stream) { }

		public ReportWriter(Stream stream , Encoding encoding) : base(stream, encoding) { }

		public ReportWriter(string path) : base(path) { }

		public ReportWriter(string path, bool append) : base(path, append) { }

		public ReportWriter(string path, bool append, Encoding encoding) : base(path, append, encoding) { }

		public void WriteSpace() {
			Write(AsciiFonts.Space);
		}

		public void WriteSpace(int length) {
			if (length <= 0) return;
			for(int i=0; i<length; ++i) WriteSpace();
		}

		public void WriteCentered(string text, int length) {
			if (MaxLineCharacters == 0) return;
			int cc = CurrentColumn;
			WriteSpace((length-text.Length)/2);
			Write(text);
			WriteSpace(length - CurrentColumn + cc);
		}

		public void Write(char value, int length) {
			for(int i=0; i<length; ++i ) Write(value);
		}
		
		public override void Write(bool value) {
			CurrentColumn += 3;
			base.Write(value?"ΝΑΙ":"ΟΧΙ");
		}

		public override void Write(char value) {
			++CurrentColumn;
			base.Write(value);
		}

		public override void Write(char[] buffer) {
			CurrentColumn += buffer.Length;
			base.Write(buffer);
		}

		public override void Write(decimal value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);
		}

		public override void Write(double value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);
		}

		public override void Write(float value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);
		}

		public override void Write(int value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);			
		}

		public override void Write(long value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);			
		}

		public override void Write(object value) {
			if (value != null) {
				IFormattable formattable = value as IFormattable;
				CurrentColumn += formattable != null
					                 ? formattable.ToString(null, this.FormatProvider).Length
					                 : value.ToString().Length;
				base.Write(value);
			}
		}

		public override void Write(string value) {
			CurrentColumn += value.Length;
			base.Write(value);
		}

		public override void Write(uint value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);			
		}

		public override void Write(ulong value) {
			CurrentColumn += value.ToString(FormatProvider).Length;
			base.Write(value);						
		}

		public override void Write(string format, object arg0) {
			CurrentColumn += String.Format(FormatProvider, format, arg0).Length;
			base.Write(format, arg0);
		}

		public override void Write(string format, params object[] arg) {
			CurrentColumn += String.Format(FormatProvider, format, arg).Length;
			base.Write(format, arg);
		}

		public override void Write(char[] buffer, int index, int count) {
			int len = count - index;
			if (len > 0) CurrentColumn += len;
			base.Write(buffer, index, count);
		}

		public override void Write(string format, object arg0, object arg1) {
			CurrentColumn += String.Format(this.FormatProvider, format, new object[] {arg0, arg1}).Length;
			base.Write(format, arg0, arg1);
		}

		public override void Write(string format, object arg0, object arg1, object arg2) {
			CurrentColumn += String.Format(this.FormatProvider, format, new object[] {arg0, arg1, arg2}).Length;
			base.Write(format, arg0, arg1, arg2);
		}

		public override void WriteLine() {
			base.WriteLine();
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(bool value) {
			base.WriteLine(value ? "ΝΑΙ" : "ΟΧΙ");
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(char value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(char[] buffer) {
			base.WriteLine(buffer);
			CurrentColumn = 0;
			++CurrentLine;
		}
		public override void WriteLine(decimal value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(double value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(float value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(int value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(long value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(object value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(string value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(uint value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(ulong value) {
			base.WriteLine(value);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(string format, object arg0) {
			base.WriteLine(format, arg0);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(string format, params object[] arg) {
			base.WriteLine(format, arg);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(char[] buffer, int index, int count) {
			base.WriteLine(buffer, index, count);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(string format, object arg0, object arg1) {
			base.WriteLine(format, arg0, arg1);
			CurrentColumn = 0;
			++CurrentLine;
		}

		public override void WriteLine(string format, object arg0, object arg1, object arg2) {
			base.WriteLine(format, arg0, arg1, arg2);
			CurrentColumn = 0;
			++CurrentLine;
		}
	}
}
